package com.share.handler;


import com.share.common.result.ResponseResult;
import com.share.constant.AuthSecurityConstants;
import com.share.exception.BaseException;
import com.share.response.ErrorResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 全局异常处理机制
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    // 处理参数校验失败异常
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public ResponseResult<ErrorResponse> handleValidationException(MethodArgumentNotValidException ex) {
        List<String> errors = ex.getBindingResult()
                .getFieldErrors()
                .stream()
                .map(error -> error.getField() + ": " + error.getDefaultMessage())
                .collect(Collectors.toList());

        ErrorResponse response = ErrorResponse.builder()
                .status(HttpStatus.BAD_REQUEST.value())
                .error(HttpStatus.BAD_REQUEST.getReasonPhrase())
                .message("参数校验失败")
                .details(errors)
                .timestamp(LocalDateTime.now())
                .build();

        return ResponseResult.success(response);
    }

    // BaseException 基础异常类
    @ExceptionHandler(value = BaseException.class)
    @ResponseBody
    public ResponseResult<Object> handleBaseException(BaseException ex) {
        return ResponseResult.builder()
                .code(ex.getStatus().getCode())
                .data(ex.getDetails())
                .msg(ex.getMessage())
                .timestamp(ex.getTimestamp())
                .build();
    }


    // 系统异常处理
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseResult<ErrorResponse> handleSystemException(
            Exception ex) {
        ErrorResponse errorResponse = ErrorResponse.builder()
                .status(HttpStatus.INTERNAL_SERVER_ERROR.value())
                .code("SYSTEM_ERROR") // 自定义错误码
                .error(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase())
                .message(ex.getMessage())
                .timestamp(LocalDateTime.now())
                .build();
        return ResponseResult.fail(errorResponse);
    }


    /**
     * 捕捉所有异常
     *
     * @param e 异常实体
     * @return 统一的异常返回
     */
    @ExceptionHandler(Throwable.class)
    public ResponseResult<Void> handleThrowable(Throwable e) {
        log.error("系统发生未知异常", e);
        return ResponseResult.fail(e.getCause().getMessage());
    }

    /**
     * 捕捉AccessDeniedException，spring security抛出的无权限访问的异常信息
     */
    @ExceptionHandler(AccessDeniedException.class)
    public ResponseResult<Object> handleAccessDeniedException(AccessDeniedException e) {
        return ResponseResult.fail(HttpStatus.FORBIDDEN.value(), AuthSecurityConstants.INSUFFICIENT_AUTHORITY);
    }


}
